//
// Created by yyl on 2021/11/25.
//

#include "MyRender.h"


MyRender *MyRender::instance = nullptr;

MyRender::MyRender() :
        viewPortWidth(0),
        viewPortHeight(0){
    memset(&renderFrame, 0, sizeof(renderFrame));
    shader = nullptr;
    shaderBefore = nullptr;
}

MyRender::~MyRender() {
    if (shader) {
        delete shader;
        shader = nullptr;
    }
    if (shaderBefore) {
        delete shaderBefore;
        shaderBefore = nullptr;
    }
}

MyRender *MyRender::GetInstance() {
    if (instance == nullptr) {
        instance = new MyRender();
    }

    return instance;
}

void MyRender::DestroyInstance() {
    if (instance) {
        delete instance;
        instance = nullptr;
    }
}

void MyRender::UpdateFrame(int format, int width, int height, uint8_t *pBuffer) {
    LOGCATE("MyRender::UpdateFrame format=%d, width=%d, height=%d, pBuffer=%p",
            format, width, height, pBuffer);
    NativeImage nativeImage;
    nativeImage.format = format;
    nativeImage.width = width;
    nativeImage.height = height;
    nativeImage.ppPlane[0] = pBuffer;

    switch (format) {
        case IMAGE_FORMAT_NV12:
        case IMAGE_FORMAT_NV21:
            nativeImage.ppPlane[1] = nativeImage.ppPlane[0] + width * height;
            break;
        case IMAGE_FORMAT_I420:
            nativeImage.ppPlane[1] = nativeImage.ppPlane[0] + width * height;
            nativeImage.ppPlane[2] = nativeImage.ppPlane[1] + width * height / 4;
            break;
        default:
            break;
    }
    if(shader){
        shader->LoadImage(&nativeImage);
    }else{
        LOGI("MyRender::UpdateFrame 没有 shader ");
    }

}

void MyRender::SetTransformMatrix(float translateX, float translateY, float scaleX, float scaleY,
                                  int degree, int mirror) {
    LOGI("MyRender::SetTransformMatrix translateX = %f, translateY = %f, scaleX = %f, scaleY = %f, degree = %d, mirror = %d",
         translateX, translateY, scaleX, scaleY, degree, mirror);
    transformMatrix.translateX = translateX;
    transformMatrix.translateY = translateY;
    transformMatrix.scaleX = scaleX;
    transformMatrix.scaleY = scaleY;
    transformMatrix.degree = degree;
    transformMatrix.mirror = mirror;
    if (shader) {
        shader->transformMatrix = transformMatrix;
    }
}

void MyRender::OnSurfaceCreated() {
    if (debug) {
        int nMaxTextureSize = 0;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &nMaxTextureSize);
        LOGI("MyRender::OnSurfaceCreated 最大纹理数量= %d", nMaxTextureSize);
    }
}

void MyRender::OnSurfaceChanged(int width, int height) {
    viewPortWidth = width;
    viewPortHeight = height;
}

void MyRender::OnSurfaceDrawFrame() {
    glViewport(0, 0, viewPortWidth, viewPortHeight);
    LOGI("MyRender:: OnSurfaceDrawFrame viewPort=%d * %d",viewPortWidth,viewPortHeight);

    if (shaderBefore) {
        shaderBefore->Destroy();
        delete shaderBefore;
        shaderBefore = nullptr;
        LOGI("MyRender  回收 shader");
    }
    if (shader) {
        shader->Init();
        shader->Draw(viewPortWidth, viewPortHeight);
    }
}
void MyRender::OnSurfaceDestroy() {
    NativeImageUtil::FreeNativeImage(&renderFrame);
    if (shader) {
        shader->Destroy();
        delete shader;
        shader = nullptr;
        LOGI("MyRender OnSurfaceDestroy  回收 shader");
    }
}



void MyRender::SetProgramType(int type) {
    if(shader){
        shaderBefore = shader;
    }
    switch (type) {
        case 0:
            shader = new SimpleShader();
            break;
        case 1:
            shader = new TriangleShader();
            break;
        case 2:
            shader = new VideoShader();
            break;

        default: {
            shader = nullptr;
        }
    }
}

void MyRender::LoadFragShaderScript(int shaderType, char *shaderString, int strLen) {
    if(shader){
        shader->LoadShaderScript(shaderType,shaderString,strLen);
    }
}


